package com.zzw.common.event;

import com.zzw.common.ApiCommonResponse;
import com.zzw.common.ApiRequest;
import com.zzw.common.CommonApi;
import com.zzw.common.exception.CommonException;
import com.zzw.requestcontext.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;

import static com.zzw.common.ApiCommonResponse.SYSTEM_ERROR;
import static com.zzw.common.ApiCommonResponse.SYSTEM_EXCEPTION;

/**
 * @author Administrator
 */
abstract public class SimpleEventService<T extends ApiRequest, E, R extends ApplicationEvent> implements CommonApi<T, E> {

    private static final Logger logger = LoggerFactory.getLogger(SimpleEventService.class);

    private final ApplicationContext applicationContext;

    protected SimpleEventService(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public abstract void checkParam(T request) throws CommonException;

    @Override
    public ApiCommonResponse<E> process(T request) {
        RequestContext requestContext = RequestContext.getInstance();
        try {
            checkParam(request);
            E business = bussiness(request);
            ApiCommonResponse<E> response = ApiCommonResponse.of(requestContext.getSn(), business);
            applicationContext.publishEvent(event(request, business));
            return response;
        } catch (CommonException e) {
            logger.error("sn:{},common exception", requestContext.getSn(), e);
            return ApiCommonResponse.of(requestContext.getSn(), e.status, e.message);
        } catch (Exception e) {
            logger.error("sn:{},exception", requestContext.getSn(), e);
            return ApiCommonResponse.of(requestContext.getSn(), SYSTEM_EXCEPTION, "system exception");
        } catch (Throwable tx) {
            logger.error("sn:{},Throwable", requestContext.getSn(), tx);
            return ApiCommonResponse.of(requestContext.getSn(), SYSTEM_ERROR, "system error");
        }
    }

    public abstract R event(T request, E response);

    public abstract E bussiness(T request) throws Exception;
}
